package topin.facecat.FaceCat.Android

import android.graphics.*
import facecat.topin.core.*
import java.util.*
import topin.facecat.FaceCat.UI.MyColor

/*
* 绘图方法
 */
class AndroidPaint : FCPaint() {
    /*
    * 图层
     */
    private var m_canvas: Canvas? = null

    /*
     * 缓存图片
     */
    private var m_cacheImage: Bitmap? = null

    /*
     * 是否双倍缓冲
     */
    private val m_doubleBufferd = true

    /*
     * 图片缓存
     */
    var m_images =
        HashMap<String, Bitmap?>()

    /*
     * 是否裁剪
     */
    private var m_isClip = false

    /*
     * 是否路径开始
     */
    private var m_isPathStart = false

    /*
     * 横向偏移
     */
    protected var m_offsetX = 0

    /*
     * 纵向偏移
     */
    protected var m_offsetY = 0

    /*
     * 透明度
     */
    protected var m_opacity = 1f

    /*
    * 绘图对象
     */
    var m_paint: Paint? = null

    /*
    * 路径
     */
    protected var m_path: Path? = null

    /*
     * 绘制区域
     */
    protected var m_pRect: FCRect? = null

    /*
     * 资源路径
     */
    protected var m_resourcePath: String? = null

    /*
     * 旋转角度
     */
    protected var m_rotateAngle = 0

    /*
     * 横向缩放
     */
    protected var m_scaleFactorX = 1.0

    /*
     * 纵向缩放
     */
    protected var m_scaleFactorY = 1.0

    /*
     * 内部图层
     */
    var m_viewCanvas: Canvas? = null

    /*
     * 画布大小
     */
    protected var m_wRect: FCRect? = null
    var m_myColor: MyColor = MyColor()

    /**
     * 添加曲线
     *
     * @param rect 矩形区域
     * @param startAngle 从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
     * @param sweepAngle 从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
     */
    override fun addArc(
        rect: FCRect,
        startAngle: Float,
        sweepAngle: Float
    ) {
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        m_path!!.addArc(andriodRect, startAngle, sweepAngle)
        m_isPathStart = false
    }

    /**
     * 添加贝赛尔曲线
     *
     * @param points 坐标数组
     */
    override fun addBezier(points: Array<FCPoint>) {
        val pointsLength = points.size
        if (pointsLength < 3) {
            return
        }
        if (m_isPathStart) {
            m_path!!.moveTo(
                points[0].x + m_offsetX.toFloat(),
                points[0].y + m_offsetY.toFloat()
            )
            m_isPathStart = false
        }
        var i = 1
        while (i < pointsLength - 1) {
            m_path!!.quadTo(
                points[i].x + m_offsetX.toFloat(), points[i].y + m_offsetY.toFloat(),
                points[i + 1].x + m_offsetX.toFloat(), points[i + 1].y + m_offsetY.toFloat()
            )
            i = i + 2
        }
        m_isPathStart = false
    }

    /**
     * 添加曲线
     *
     * @param points 点阵
     */
    override fun addCurve(points: Array<FCPoint>) {}

    /**
     * 添加椭圆
     *
     * @param rect 矩形
     */
    override fun addEllipse(rect: FCRect) {
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        m_path!!.addOval(andriodRect, Path.Direction.CW)
        m_isPathStart = false
    }

    /**
     * 添加直线
     *
     * @param x1 第一个点的横坐标
     * @param y1 第一个点的纵坐标
     * @param x2 第二个点的横坐标
     * @param y2 第二个点的纵坐标
     */
    override fun addLine(x1: Int, y1: Int, x2: Int, y2: Int) {
        var lx1 = x1 + m_offsetX.toFloat()
        var ly1 = y1 + m_offsetY.toFloat()
        var lx2 = x2 + m_offsetX.toFloat()
        var ly2 = y2 + m_offsetY.toFloat()
        if (m_scaleFactorX != 1.0 || m_scaleFactorY != 1.0) {
            lx1 = (m_scaleFactorX * lx1).toFloat()
            ly1 = (m_scaleFactorY * ly1).toFloat()
            lx2 = (m_scaleFactorX * lx2).toFloat()
            ly2 = (m_scaleFactorY * ly2).toFloat()
        }
        if (m_isPathStart) {
            m_path!!.moveTo(lx1, ly1)
            m_isPathStart = false
        }
        m_path!!.lineTo(lx2, ly2)
    }

    /**
     * 添加扇形
     *
     * @param rect 矩形区域
     * @param startAngle 从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
     * @param sweepAngle 从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
     */
    override fun addPie(
        rect: FCRect,
        startAngle: Float,
        sweepAngle: Float
    ) {
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        m_path!!.addArc(andriodRect, startAngle, sweepAngle)
        m_isPathStart = false
    }

    /**
     * 添加矩形
     *
     * @param rect 区域
     */
    override fun addRect(rect: FCRect) {
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        m_path!!.addRect(andriodRect, Path.Direction.CW)
        m_isPathStart = false
    }

    /**
     * 添加图片
     * @param key 键
     * @param image 图片
     */
    fun addSourceImage(key: String, image: Bitmap?) {
        m_images[key] = image
    }

    /**
     * 添加文字
     *
     * @param text 文字
     * @param font 字体
     * @param rect 区域
     */
    override fun addText(
        text: String,
        font: FCFont,
        rect: FCRect,
        width: Int
    ) {
    }

    /**
     * 自动缩放矩形
     *
     * @param andriodRect 矩形
     */
    protected fun affectScaleFactor(andriodRect: RefObject<RectF>) {
        if (m_scaleFactorX != -1.0 || m_scaleFactorY != -1.0) {
            andriodRect.argvalue.left = (andriodRect.argvalue.left * m_scaleFactorX).toFloat();
            andriodRect.argvalue.top = (andriodRect.argvalue.top * m_scaleFactorY).toFloat();
            andriodRect.argvalue.right = (andriodRect.argvalue.right * m_scaleFactorX).toFloat();
            andriodRect.argvalue.bottom = (andriodRect.argvalue.bottom * m_scaleFactorY).toFloat();
        }
    }

    /**
     * 开始绘图
     *
     * @param hDC HDC
     * @param wRect 窗体区域
     * @param pRect 刷新区域
     */
    override fun beginPaint(hDC: Int, wRect: FCRect, pRect: FCRect) {
        val width = wRect.right - wRect.left
        var height = wRect.bottom - wRect.top
        m_wRect = wRect.clone()
        m_pRect = pRect.clone()
        m_paint = Paint()
        if (m_doubleBufferd) {
            if (m_cacheImage == null || m_cacheImage!!.width != width || m_cacheImage!!.height != height) {
                if (width > height) {
                    height *= 2
                }
                if (m_cacheImage != null) {
                    m_cacheImage!!.recycle()
                }
                m_cacheImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
            }
            val cachePaint = Paint()
            cachePaint.isAntiAlias = true
            m_viewCanvas!!.drawBitmap(m_cacheImage!!, 0f, 0f, cachePaint)
            m_canvas = Canvas(m_cacheImage!!)
            m_viewCanvas!!.save()
        } else {
            m_canvas = m_viewCanvas
        }
        m_canvas!!.drawFilter = PaintFlagsDrawFilter(
            0,
            Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG
        )
        m_isClip = false
        m_opacity = 1f
        m_resourcePath = null
    }

    /**
     * 开始一段路径
     */
    override fun beginPath() {
        m_path = Path()
        m_isPathStart = true
    }

    /**
     * 清除缓存
     */
    override fun clearCaches() {
        val hashMap =
            HashMap<String, Bitmap>()
        for (key in hashMap.keys) {
            val value = hashMap[key]
            value!!.recycle()
        }
        m_images.clear()
    }

    /**
     * 裁剪路径
     */
    override fun clipPath() {
        m_canvas!!.clipPath(m_path!!)
    }

    /**
     * 闭合路径
     */
    override fun closeFigure() {
        m_path!!.close()
    }

    /**
     * 结束一段路径
     */
    override fun closePath() {
        m_path!!.reset()
        m_path = null
        m_isPathStart = false
    }

    /**
     * 删除对象
     */
    override fun delete() {
        clearCaches()
        if (m_cacheImage != null) {
            m_cacheImage!!.recycle()
            m_cacheImage = null
        }
    }

    /**
     * 绘制弧线
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param rect 矩形区域
     * @param startAngle 从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
     * @param sweepAngle 从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
     */
    override fun drawArc(
        dwPenColor: Long,
        width: Float,
        style: Int,
        rect: FCRect,
        startAngle: Float,
        sweepAngle: Float
    ) {
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        setDrawPaint(dwPenColor, width, style)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawArc(andriodRect, startAngle, sweepAngle, false, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制贝赛尔曲线
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param points 坐标阵
     */
    override fun drawBezier(
        dwPenColor: Long,
        width: Float,
        style: Int,
        points: Array<FCPoint>
    ) {
        if (dwPenColor == FCColor.None) return
        val path = Path()
        val cpt = points.size
        if (cpt < 3) {
            return
        }
        path.moveTo(points[0].x + m_offsetX.toFloat(), points[0].y + m_offsetY.toFloat())
        var i = 1
        while (i < points.size - 1) {
            path.quadTo(
                points[i].x + m_offsetX.toFloat(), points[i].y + m_offsetY.toFloat(),
                points[i + 1].x + m_offsetX.toFloat(), points[i + 1].y + m_offsetY.toFloat()
            )
            i = i + 2
        }
        setDrawPaint(dwPenColor, width, style)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawPath(path, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制曲线
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param points 坐标阵
     */
    override fun drawCurve(
        dwPenColor: Long,
        width: Float,
        style: Int,
        points: Array<FCPoint>
    ) {
    }

    /**
     * 绘制椭圆
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param rect 矩形区域
     */
    override fun drawEllipse(
        dwPenColor: Long,
        width: Float,
        style: Int,
        rect: FCRect
    ) {
        if (dwPenColor == FCColor.None) return
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        setDrawPaint(dwPenColor, width, style)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawOval(andriodRect, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制椭圆
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param left 左侧坐标
     * @param top 顶部左标
     * @param right 右侧坐标
     * @param bottom 底部坐标
     */
    override fun drawEllipse(
        dwPenColor: Long,
        width: Float,
        style: Int,
        left: Int,
        top: Int,
        right: Int,
        bottom: Int
    ) {
        val rect = FCRect(left, top, right, bottom)
        drawEllipse(dwPenColor, width, style, rect)
    }

    /**
     * 绘制图片
     *
     * @param imagePath 图片路径
     * @param rect 绘制区域
     */
    override fun drawImage(imagePath: String, rect: FCRect) {
        var drawImage: Bitmap? = null
        var rw = rect.right - rect.left
        if (rw < 1) rw = 1
        var rh = rect.bottom - rect.top
        if (rh < 1) rh = 1
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        if (m_images.containsKey(imagePath)) {
            drawImage = m_images[imagePath]
        } else {
            if (FCFile.isFileExist(
                    imagePath.replace(".png", "").replace(".jpg", "").replace(".jpeg", "")
                )
            ) {
                drawImage = BitmapFactory.decodeFile(
                    imagePath.replace(".png", "").replace(".jpg", "").replace(".jpeg", "")
                )
                drawImage?.let { addSourceImage(imagePath, it) }
            }
        }
        if (drawImage != null) {
            val refAndriodRect = RefObject(andriodRect)
            affectScaleFactor(refAndriodRect)
            andriodRect = refAndriodRect.argvalue
            m_paint!!.isAntiAlias = true
            setFillPaint(FCColor.rgb(255, 255, 255))
            m_canvas!!.drawBitmap(
                drawImage,
                Rect(0, 0, drawImage.width, drawImage.height),
                andriodRect,
                m_paint
            )
            m_paint!!.isAntiAlias = false
        }
    }

    /**
     * 绘制直线
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param x1 第一个点的横坐标
     * @param y1 第一个点的纵坐标
     * @param x2 第二个点的横坐标
     * @param y2 第二个点的纵坐标
     */
    override fun drawLine(
        dwPenColor: Long,
        width: Float,
        style: Int,
        x1: Int,
        y1: Int,
        x2: Int,
        y2: Int
    ) {
        if (dwPenColor == FCColor.None) return
        var lx1 = x1 + m_offsetX.toFloat()
        var ly1 = y1 + m_offsetY.toFloat()
        var lx2 = x2 + m_offsetX.toFloat()
        var ly2 = y2 + m_offsetY.toFloat()
        if (m_scaleFactorX != 1.0 || m_scaleFactorY != 1.0) {
            lx1 = (m_scaleFactorX * lx1).toFloat()
            ly1 = (m_scaleFactorY * ly1).toFloat()
            lx2 = (m_scaleFactorX * lx2).toFloat()
            ly2 = (m_scaleFactorY * ly2).toFloat()
        }
        setDrawPaint(dwPenColor, width, style)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawLine(lx1, ly1, lx2, ly2, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制直线
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param x 第一个点坐标
     * @param y 第二个点的坐标
     */
    override fun drawLine(
        dwPenColor: Long,
        width: Float,
        style: Int,
        x: FCPoint,
        y: FCPoint
    ) {
        drawLine(dwPenColor, width, style, x.x, x.y, y.x, y.y)
    }

    /**
     * 绘制路径
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     */
    override fun drawPath(
        dwPenColor: Long,
        width: Float,
        style: Int
    ) {
        if (dwPenColor == FCColor.None) return
        setDrawPaint(dwPenColor, width, style)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawPath(m_path!!, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制弧线
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param rect 矩形区域
     * @param startAngle 从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
     * @param sweepAngle 从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
     */
    override fun drawPie(
        dwPenColor: Long,
        width: Float,
        style: Int,
        rect: FCRect,
        startAngle: Float,
        sweepAngle: Float
    ) {
        if (dwPenColor == FCColor.None) return
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        setDrawPaint(dwPenColor, width, style)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawArc(andriodRect, startAngle, sweepAngle, true, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制多边形
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param points 点的数组
     */
    override fun drawPolygon(
        dwPenColor: Long,
        width: Float,
        style: Int,
        points: Array<FCPoint>
    ) {
        if (dwPenColor == FCColor.None) return
        val path = Path()
        var fx = 0
        var fy = 0
        val cpt = points.size
        for (i in 0 until cpt) {
            var x = points[i].x + m_offsetX
            var y = points[i].y + m_offsetY
            if (m_scaleFactorX != 1.0 || m_scaleFactorY != 1.0) {
                x = (m_scaleFactorX * x).toInt()
                y = (m_scaleFactorY * y).toInt()
            }
            if (i == 0) {
                fx = x
                fy = y
                path.moveTo(x.toFloat(), y.toFloat())
            } else {
                path.lineTo(x.toFloat(), y.toFloat())
            }
        }
        path.close()
        setDrawPaint(dwPenColor, width, style)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawPath(path, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制大量直线
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param points 点集
     */
    override fun drawPolyline(
        dwPenColor: Long,
        width: Float,
        style: Int,
        points: Array<FCPoint>
    ) {
        if(points.size == 1){
            drawLine(dwPenColor, width, style, points[0].x, points[0].y, points[0].x, points[0].y);
            return;
        }
        if (dwPenColor == FCColor.None) return
        val path = Path()
        var fx = 0
        var fy = 0
        val cpt = points.size
        for (i in 0 until cpt) {
            var x = points[i].x + m_offsetX
            var y = points[i].y + m_offsetY
            if (m_scaleFactorX != 1.0 || m_scaleFactorY != 1.0) {
                x = (m_scaleFactorX * x).toInt()
                y = (m_scaleFactorY * y).toInt()
            }
            if (i == 0) {
                fx = x
                fy = y
                path.moveTo(x.toFloat(), y.toFloat())
            } else {
                path.lineTo(x.toFloat(), y.toFloat())
            }
        }
        setDrawPaint(dwPenColor, width, style)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawPath(path, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制矩形
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param rect 矩形区域
     */
    override fun drawRect(
        dwPenColor: Long,
        width: Float,
        style: Int,
        rect: FCRect
    ) {
        drawRect(dwPenColor, width, style, rect.left, rect.top, rect.right, rect.bottom)
    }

    /**
     * 绘制矩形
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param left 左侧坐标
     * @param top 顶部左标
     * @param right 右侧坐标
     * @param bottom 底部坐标
     */
    override fun drawRect(
        dwPenColor: Long,
        width: Float,
        style: Int,
        left: Int,
        top: Int,
        right: Int,
        bottom: Int
    ) {
        if (dwPenColor == FCColor.None) return
        val andriodRect =
            RectF(
                (left + m_offsetX).toFloat(),
                (top + m_offsetY).toFloat(),
                (right + m_offsetX).toFloat(),
                (bottom + m_offsetY).toFloat()
            )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        setDrawPaint(dwPenColor, width, style)
        m_paint!!.isAntiAlias = false
        m_canvas!!.drawRect(andriodRect, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制圆角矩形
     *
     * @param dwPenColor 颜色
     * @param width 宽度
     * @param style 样式
     * @param rect 矩形区域
     * @param cornerRadius 边角半径
     */
    override fun drawRoundRect(
        dwPenColor: Long,
        width: Float,
        style: Int,
        rect: FCRect,
        cornerRadius: Int
    ) {
        if (cornerRadius == 0) {
            drawRect(dwPenColor, width, style, rect)
        } else {
            if (dwPenColor == FCColor.None) return
            val andriodRect = RectF(
                (rect.left + m_offsetX).toFloat(),
                (rect.top + m_offsetY).toFloat(),
                (rect.right + m_offsetX).toFloat(),
                (rect.bottom + m_offsetY).toFloat()
            )
            val refAndriodRect = RefObject(andriodRect)
            affectScaleFactor(refAndriodRect)
            val path = Path()
            path.addRoundRect(
                andriodRect,
                (cornerRadius * Math.min(m_scaleFactorX, m_scaleFactorY)).toFloat(),
                (cornerRadius * Math.min(m_scaleFactorX, m_scaleFactorY)).toFloat(),
                Path.Direction.CW
            )
            path.close()
            setDrawPaint(dwPenColor, width, style)
            m_paint!!.isAntiAlias = true
            m_canvas!!.drawPath(path, m_paint!!)
            m_paint!!.isAntiAlias = false
        }
    }

    /**
     * 绘制文字
     *
     * @param text 文字
     * @param dwPenColor 颜色
     * @param font 字体
     * @param rect 矩形区域
     */
    override fun drawText(
        text: String,
        dwPenColor: Long,
        font: FCFont,
        rect: FCRect,
        width: Int
    ) {
        if (dwPenColor == FCColor.None || text == null) return
        if (m_scaleFactorX != 1.0 || m_scaleFactorY != 1.0) {
            val andriodRect = RectF(
                (rect.left + m_offsetX).toFloat(),
                (rect.top + m_offsetY).toFloat(),
                (rect.right + m_offsetX).toFloat(),
                (rect.bottom + m_offsetY).toFloat()
            )
            val refAndriodRect = RefObject(andriodRect)
            affectScaleFactor(refAndriodRect)
            val fontSize =
                (font.m_fontSize * (m_scaleFactorX + m_scaleFactorY) / 2).toFloat()
            val fontFamily = font.m_fontFamily
            var newFont = ""
            newFont = if (fontFamily == "Default") {
                MyColor.systemFont
            } else {
                font.m_fontFamily
            }
            if (newFont != m_lastFont) {
                if (newFont == "Default") {
                    m_paint!!.typeface = Typeface.DEFAULT
                } else {
                    try {
                        if (m_typeFaces.containsKey(newFont)) {
                            val tf = m_typeFaces[newFont]
                            if (tf !== m_paint!!.typeface) {
                                m_paint!!.typeface = m_typeFaces[newFont]
                            }
                        } else {
                            val tf =
                                Typeface.createFromFile("/system/fonts/$newFont.ttf")
                            if (tf != null) {
                                m_paint!!.typeface = tf
                                m_typeFaces[newFont] = tf
                            }
                        }
                    } catch (ex: Exception) {
                    }
                }
                m_lastFont = newFont
            }
            m_paint!!.textSize = fontSize
            m_paint!!.isFakeBoldText = font.m_bold
            m_paint!!.setTextSkewX(if (font.m_italic) -0.5f else 0.0f)
            m_paint!!.isUnderlineText = font.m_underline
            val fm = m_paint!!.fontMetrics
            setFillPaint(dwPenColor)
            m_paint!!.isAntiAlias = true
            val baseLineY =
                (andriodRect.bottom + andriodRect.top - fm.bottom - fm.top) / 2
            if (font.m_angle != 0) {
                m_canvas!!.save()
                m_canvas!!.translate(
                    andriodRect.left + andriodRect.right - andriodRect.left,
                    andriodRect.top + (andriodRect.bottom - andriodRect.top) / 2
                )
                m_canvas!!.rotate(font.m_angle.toFloat())
                m_canvas!!.drawText(
                    text,
                    -(andriodRect.right - andriodRect.left) / 2,
                    -(andriodRect.bottom - andriodRect.top) / 2,
                    m_paint!!
                )
                m_canvas!!.restore()
            } else {
                m_canvas!!.drawText(text, andriodRect.left, baseLineY, m_paint!!)
            }
            m_paint!!.isAntiAlias = false
        } else {
            val fontFamily = font.m_fontFamily
            var newFont = ""
            newFont = if (fontFamily == "Default") {
                val sysFont = "System"
                if (sysFont == "System") {
                    "Default"
                } else {
                    sysFont
                }
            } else {
                font.m_fontFamily
            }
            if (newFont != m_lastFont) {
                if (newFont == "Default") {
                    m_paint!!.typeface = Typeface.DEFAULT
                } else {
                    try {
                        if (m_typeFaces.containsKey(newFont)) {
                            val tf = m_typeFaces[newFont]
                            if (tf !== m_paint!!.typeface) {
                                m_paint!!.typeface = m_typeFaces[newFont]
                            }
                        } else {
                            val tf =
                                Typeface.createFromFile("/system/fonts/$newFont.ttf")
                            if (tf != null) {
                                m_paint!!.typeface = tf
                                m_typeFaces[newFont] = tf
                            }
                        }
                    } catch (ex: Exception) {
                    }
                }
                m_lastFont = newFont
            }
            m_paint!!.textSize = font.m_fontSize
            m_paint!!.isFakeBoldText = font.m_bold
            m_paint!!.setTextSkewX(if (font.m_italic) -0.5f else 0.0f)
            m_paint!!.isUnderlineText = font.m_underline
            val andriodRect = RectF(
                (rect.left + m_offsetX).toFloat(),
                (rect.top + m_offsetY).toFloat(),
                (rect.right + m_offsetX).toFloat(),
                (rect.bottom + m_offsetY).toFloat()
            )
            val fm = m_paint!!.fontMetrics
            setFillPaint(dwPenColor)
            m_paint!!.isAntiAlias = true
            //            m_canvas.drawText(text, andriodRect.left, andriodRect.top  + (fm.descent - fm.ascent), m_paint);
            val baseLineY =
                (andriodRect.bottom + andriodRect.top - fm.bottom - fm.top) / 2
            if (font.m_angle != 0) {
                m_canvas!!.save()
                m_canvas!!.translate(
                    andriodRect.left + andriodRect.right - andriodRect.left,
                    andriodRect.top + (andriodRect.bottom - andriodRect.top) / 2
                )
                m_canvas!!.rotate(font.m_angle.toFloat())
                m_canvas!!.drawText(
                    text,
                    -(andriodRect.right - andriodRect.left) / 2,
                    -(andriodRect.bottom - andriodRect.top) / 2,
                    m_paint!!
                )
                m_canvas!!.restore()
            } else {
                m_canvas!!.drawText(text, andriodRect.left, baseLineY, m_paint!!)
            }
            m_paint!!.isAntiAlias = false
        }
    }

    /**
     * 绘制文字
     *
     * @param text 文字
     * @param dwPenColor 颜色
     * @param font 字体
     * @param rect 矩形区域
     */
    override fun drawText(
        text: String,
        dwPenColor: Long,
        font: FCFont,
        rect: FCRectF,
        width: Int
    ) {
        if (dwPenColor == FCColor.None || text == null) return
        if (m_scaleFactorX != 1.0 || m_scaleFactorY != 1.0) {
            val andriodRect = RectF(
                rect.left + m_offsetX,
                rect.top + m_offsetY,
                rect.right + m_offsetX,
                rect.bottom + m_offsetY
            )
            val refAndriodRect = RefObject(andriodRect)
            affectScaleFactor(refAndriodRect)
            val fontSize =
                (font.m_fontSize * (m_scaleFactorX + m_scaleFactorY) / 2).toFloat()
            val fontFamily = font.m_fontFamily
            var newFont = ""
            newFont = if (fontFamily == "Default") {
                val sysFont = "System"
                if (sysFont == "System") {
                    "Default"
                } else {
                    sysFont
                }
            } else {
                font.m_fontFamily
            }
            if (newFont != m_lastFont) {
                if (newFont == "Default") {
                    m_paint!!.typeface = Typeface.DEFAULT
                } else {
                    try {
                        if (m_typeFaces.containsKey(newFont)) {
                            val tf = m_typeFaces[newFont]
                            if (tf !== m_paint!!.typeface) {
                                m_paint!!.typeface = m_typeFaces[newFont]
                            }
                        } else {
                            val tf =
                                Typeface.createFromFile("/system/fonts/$newFont.ttf")
                            if (tf != null) {
                                m_paint!!.typeface = tf
                                m_typeFaces[newFont] = tf
                            }
                        }
                    } catch (ex: Exception) {
                    }
                }
                m_lastFont = newFont
            }
            m_paint!!.textSize = fontSize
            m_paint!!.isFakeBoldText = font.m_bold
            m_paint!!.setTextSkewX(if (font.m_italic) -0.5f else 0.0f)
            m_paint!!.isUnderlineText = font.m_underline
            val fm = m_paint!!.fontMetrics
            setFillPaint(dwPenColor)
            m_paint!!.isAntiAlias = true
            val baseLineY =
                (andriodRect.bottom + andriodRect.top - fm.bottom - fm.top) / 2
            if (font.m_angle != 0) {
                m_canvas!!.save()
                m_canvas!!.translate(
                    andriodRect.left + (andriodRect.right - andriodRect.left) / 2,
                    andriodRect.top + (andriodRect.bottom - andriodRect.top) / 2
                )
                m_canvas!!.rotate(font.m_angle.toFloat())
                m_canvas!!.drawText(
                    text,
                    -(andriodRect.right - andriodRect.left) / 2,
                    -(andriodRect.bottom - andriodRect.top) / 2,
                    m_paint!!
                )
                m_canvas!!.restore()
            } else {
                m_canvas!!.drawText(text, andriodRect.left, baseLineY, m_paint!!)
            }
            m_paint!!.isAntiAlias = false
        } else {
            val fontFamily = font.m_fontFamily
            var newFont = ""
            newFont = if (fontFamily == "Default") {
                MyColor.systemFont
            } else {
                font.m_fontFamily
            }
            if (newFont != m_lastFont) {
                if (newFont == "Default") {
                    m_paint!!.typeface = Typeface.DEFAULT
                } else {
                    try {
                        if (m_typeFaces.containsKey(newFont)) {
                            val tf = m_typeFaces[newFont]
                            if (tf !== m_paint!!.typeface) {
                                m_paint!!.typeface = m_typeFaces[newFont]
                            }
                        } else {
                            val tf =
                                Typeface.createFromFile("/system/fonts/$newFont.ttf")
                            if (tf != null) {
                                m_paint!!.typeface = tf
                                m_typeFaces[newFont] = tf
                            }
                        }
                    } catch (ex: Exception) {
                    }
                }
                m_lastFont = newFont
            }
            m_paint!!.textSize = font.m_fontSize
            m_paint!!.isFakeBoldText = font.m_bold
            m_paint!!.setTextSkewX(if (font.m_italic) -0.5f else 0.0f)
            m_paint!!.isUnderlineText = font.m_underline
            val andriodRect = RectF(
                rect.left + m_offsetX,
                rect.top + m_offsetY,
                rect.right + m_offsetX,
                rect.bottom + m_offsetY
            )
            val fm = m_paint!!.fontMetrics
            setFillPaint(dwPenColor)
            m_paint!!.isAntiAlias = true
            //            m_canvas.drawText(text, andriodRect.left, andriodRect.top  + (fm.descent - fm.ascent), m_paint);
            val baseLineY =
                (andriodRect.bottom + andriodRect.top - fm.bottom - fm.top) / 2
            if (font.m_angle != 0) {
                m_canvas!!.save()
                m_canvas!!.translate(
                    andriodRect.left + (andriodRect.right - andriodRect.left) / 2,
                    andriodRect.top + (andriodRect.bottom - andriodRect.top) / 2
                )
                m_canvas!!.rotate(font.m_angle.toFloat())
                m_canvas!!.drawText(
                    text,
                    -(andriodRect.right - andriodRect.left) / 2,
                    -(andriodRect.bottom - andriodRect.top) / 2,
                    m_paint!!
                )
                m_canvas!!.restore()
            } else {
                m_canvas!!.drawText(text, andriodRect.left, baseLineY, m_paint!!)
            }
            m_paint!!.isAntiAlias = false
        }
    }

    /**
     * 绘制自动省略结尾的文字
     *
     * @param text 文字
     * @param dwPenColor 颜色
     * @param font 字体
     * @param rect 矩形区域
     */
    override fun drawTextAutoEllipsis(
        text: String,
        dwPenColor: Long,
        font: FCFont,
        rect: FCRect
    ) {
        drawText(text, dwPenColor, font, rect, -1)
    }

    /**
     * 结束绘图
     */
    override fun endPaint() {
        m_paint!!.pathEffect = null
        var andriodRect = RectF(
            m_pRect!!.left.toFloat(),
            m_pRect!!.top.toFloat(),
            m_pRect!!.right.toFloat(),
            m_pRect!!.bottom.toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        if (m_doubleBufferd) {
            m_viewCanvas!!.restore()
        }
        if (m_isClip) {
            if (m_doubleBufferd) {
                m_canvas!!.restore()
            } else {
                m_viewCanvas!!.restore()
            }
        }
        m_isClip = false
        m_offsetX = 0
        m_offsetY = 0
        m_resourcePath = ""
    }

    /**
     * 反裁剪区域
     */
    override fun excludeClipPath() {
        m_canvas!!.clipPath(m_path!!, Region.Op.XOR)
    }

    /**
     * 填充椭圆
     *
     * @param dwPenColor 颜色
     * @param rect 矩形区域
     */
    override fun fillEllipse(dwPenColor: Long, rect: FCRect) {
        if (dwPenColor == FCColor.None) return
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        setFillPaint(dwPenColor)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawOval(andriodRect, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 填充椭圆
     *
     * @param dwPenColor 颜色
     * @param left 左侧坐标
     * @param top 顶部左标
     * @param right 右侧坐标
     * @param bottom 底部坐标
     */
    override fun fillEllipse(
        dwPenColor: Long,
        left: Int,
        top: Int,
        right: Int,
        bottom: Int
    ) {
        val newRect = FCRect(left, top, right, bottom)
        fillEllipse(dwPenColor, newRect)
    }

    /**
     * 绘制渐变椭圆
     *
     * @param dwFirst 开始颜色
     * @param dwSecond 结束颜色
     * @param rect 矩形
     * @param angle 角度
     */
    override fun fillGradientEllipse(
        dwFirst: Long,
        dwSecond: Long,
        rect: FCRect,
        angle: Int
    ) {
        if (dwFirst == FCColor.None) return
        if (dwSecond == FCColor.None) return
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        val shade = LinearGradient(
            andriodRect.left, andriodRect.top, andriodRect.left, andriodRect.bottom,
            getAndriodColor(dwFirst), getAndriodColor(dwSecond), Shader.TileMode.REPEAT
        )
        m_paint!!.shader = shade
        setFillPaint(dwFirst)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawOval(andriodRect, m_paint!!)
        m_paint!!.isAntiAlias = false
        m_paint!!.shader = null
    }

    /**
     * 填充渐变路径
     *
     * @param dwFirst 开始颜色
     * @param dwSecond 结束颜色
     * @param rect 点的集合
     * @param angle 角度
     */
    override fun fillGradientPath(
        dwFirst: Long,
        dwSecond: Long,
        rect: FCRect,
        angle: Int
    ) {
        if (dwFirst == FCColor.None) return
        if (dwSecond == FCColor.None) return
        val path = Path()
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        val shade = LinearGradient(
            andriodRect.left, andriodRect.top, andriodRect.left, andriodRect.bottom,
            getAndriodColor(dwFirst), getAndriodColor(dwSecond), Shader.TileMode.REPEAT
        )
        m_paint!!.shader = shade
        path.addRect(andriodRect, Path.Direction.CW)
        setFillPaint(dwFirst)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawPath(path, m_paint!!)
        m_paint!!.isAntiAlias = false
        m_paint!!.shader = null
    }

    /**
     * 绘制渐变的多边形
     *
     * @param dwFirst 开始颜色
     * @param dwSecond 结束颜色
     * @param points 点的集合
     * @param angle 角度
     */
    override fun fillGradientPolygon(
        dwFirst: Long,
        dwSecond: Long,
        points: Array<FCPoint>,
        angle: Int
    ) {
        if (dwFirst == FCColor.None) return
        if (dwSecond == FCColor.None) return
        val path = Path()
        var minX = 0
        var minY = 0
        var maxX = 0
        var maxY = 0
        var fx = 0
        var fy = 0
        val cpt = points.size
        for (i in 0 until cpt) {
            var x = points[i].x + m_offsetX
            var y = points[i].y + m_offsetY
            if (m_scaleFactorX != 1.0 || m_scaleFactorY != 1.0) {
                x = (m_scaleFactorX * x).toInt()
                y = (m_scaleFactorY * y).toInt()
            }
            if (i == 0) {
                fx = x
                fy = y
                maxX = x
                maxY = y
                path.moveTo(x.toFloat(), y.toFloat())
            } else {
                path.lineTo(x.toFloat(), y.toFloat())
            }
            if (minX > x) {
                minX = x
            }
            if (minY > y) {
                minY = y
            }
            if (maxX < x) {
                maxX = x
            }
            if (maxY < y) {
                maxY = y
            }
        }
        path.close()
        val shade = LinearGradient(
            minX.toFloat(), minY.toFloat(), minX.toFloat(), maxY.toFloat(), getAndriodColor(dwFirst),
            getAndriodColor(dwSecond), Shader.TileMode.REPEAT
        )
        m_paint!!.shader = shade
        setFillPaint(dwFirst)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawPath(path, m_paint!!)
        m_paint!!.isAntiAlias = false
        m_paint!!.shader = null
    }

    /**
     * 绘制渐变矩形
     *
     * @param dwFirst 开始颜色
     * @param dwSecond 结束颜色
     * @param rect 矩形
     * @param cornerRadius 圆角半径
     * @param angle 角度
     */
    override fun fillGradientRect(
        dwFirst: Long,
        dwSecond: Long,
        rect: FCRect,
        cornerRadius: Int,
        angle: Int
    ) {
        if (dwFirst == FCColor.None) return
        if (dwSecond == FCColor.None) return
        val path = Path()
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        val shade = LinearGradient(
            andriodRect.left, andriodRect.top, andriodRect.left, andriodRect.bottom,
            getAndriodColor(dwFirst), getAndriodColor(dwSecond), Shader.TileMode.REPEAT
        )
        m_paint!!.shader = shade
        if (cornerRadius > 0) {
            path.addRoundRect(
                andriodRect,
                cornerRadius.toFloat(),
                cornerRadius.toFloat(),
                Path.Direction.CW
            )
        } else {
            path.addRect(andriodRect, Path.Direction.CW)
        }
        setFillPaint(dwFirst)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawPath(path, m_paint!!)
        m_paint!!.isAntiAlias = false
        path.close()
        m_paint!!.shader = null
    }

    /**
     * 填充路径
     *
     * @param dwPenColor 颜色
     */
    override fun fillPath(dwPenColor: Long) {
        if (dwPenColor == FCColor.None) return
        setFillPaint(dwPenColor)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawPath(m_path!!, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 绘制扇形
     *
     * @param dwPenColor 颜色
     * @param rect 矩形区域
     * @param startAngle 从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
     * @param sweepAngle 从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
     */
    override fun fillPie(
        dwPenColor: Long,
        rect: FCRect,
        startAngle: Float,
        sweepAngle: Float
    ) {
        if (dwPenColor == FCColor.None) return
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        setFillPaint(dwPenColor)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawArc(andriodRect, startAngle, sweepAngle, true, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 填充多边形
     *
     * @param dwPenColor 颜色
     * @param points 点的数组
     */
    override fun fillPolygon(
        dwPenColor: Long,
        points: Array<FCPoint>
    ) {
        if (dwPenColor == FCColor.None) return
        val path = Path()
        var fx = 0
        var fy = 0
        val cpt = points.size
        for (i in 0 until cpt) {
            var x = points[i].x + m_offsetX
            var y = points[i].y + m_offsetY
            if (m_scaleFactorX != 1.0 || m_scaleFactorY != 1.0) {
                x = (m_scaleFactorX * x).toInt()
                y = (m_scaleFactorY * y).toInt()
            }
            if (i == 0) {
                fx = x
                fy = y
                path.moveTo(x.toFloat(), y.toFloat())
            } else {
                path.lineTo(x.toFloat(), y.toFloat())
            }
        }
        path.close()
        setFillPaint(dwPenColor)
        m_paint!!.isAntiAlias = true
        m_canvas!!.drawPath(path, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 填充矩形
     *
     * @param dwPenColor 颜色
     * @param rect 矩形区域
     */
    override fun fillRect(dwPenColor: Long, rect: FCRect) {
        if (dwPenColor == FCColor.None) return
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        setFillPaint(dwPenColor)
        m_paint!!.isAntiAlias = false
        m_canvas!!.drawRect(andriodRect, m_paint!!)
        m_paint!!.isAntiAlias = false
    }

    /**
     * 填充矩形
     *
     * @param dwPenColor 颜色
     * @param left 左侧坐标
     * @param top 顶部左标
     * @param right 右侧坐标
     * @param bottom 底部坐标
     */
    override fun fillRect(
        dwPenColor: Long,
        left: Int,
        top: Int,
        right: Int,
        bottom: Int
    ) {
        val newRect = FCRect(left, top, right, bottom)
        fillRect(dwPenColor, newRect)
    }

    /**
     * 填充圆角矩形
     *
     * @param dwPenColor 颜色
     * @param rect 矩形区域
     * @param cornerRadius 边角半径
     */
    override fun fillRoundRect(
        dwPenColor: Long,
        rect: FCRect,
        cornerRadius: Int
    ) {
        if (cornerRadius == 0) {
            fillRect(dwPenColor, rect)
        } else {
            if (dwPenColor == FCColor.None) return
            var andriodRect = RectF(
                (rect.left + m_offsetX).toFloat(),
                (rect.top + m_offsetY).toFloat(),
                (rect.right + m_offsetX).toFloat(),
                (rect.bottom + m_offsetY).toFloat()
            )
            val refAndriodRect = RefObject(andriodRect)
            affectScaleFactor(refAndriodRect)
            andriodRect = refAndriodRect.argvalue
            val path = Path()
            path.addRoundRect(
                andriodRect,
                (cornerRadius * Math.min(m_scaleFactorX, m_scaleFactorY)).toFloat(),
                (cornerRadius * Math.min(m_scaleFactorX, m_scaleFactorY)).toFloat(),
                Path.Direction.CW
            )
            path.close()
            setFillPaint(dwPenColor)
            m_paint!!.isAntiAlias = true
            m_canvas!!.drawPath(path, m_paint!!)
            m_paint!!.isAntiAlias = false
        }
    }

    /**
     * 获取颜色
     *
     * @param dwPenColor 输入颜色
     * @returns 输出颜色
     */
    override fun getColor(dwPenColor: Long): Long {
        var color = dwPenColor
        if (dwPenColor < FCColor.None) {
            color = m_myColor.getUserColor(dwPenColor)
        }
        return color
    }

    /**
     * 获取安卓的颜色
     *
     * @param dwPenColor 输入颜色
     * @returns 输出颜色
     */
    fun getAndriodColor(dwPenColor: Long): Int {
        val dwPenColor2 = getPaintColor(dwPenColor)
        var a = 0
        var r = 0
        var g = 0
        var b = 0
        val refA = RefObject(a)
        val refR = RefObject(r)
        val refG = RefObject(g)
        val refB = RefObject(b)
        FCColor.toRgba(this, dwPenColor2, refR, refG, refB, refA)
        a = refA.argvalue
        r = refR.argvalue
        g = refG.argvalue
        b = refB.argvalue
        return if (m_opacity < 1) {
            Color.argb((a * m_opacity).toInt(), r, g, b)
        } else {
            Color.argb(a, r, g, b)
        }
    }

    /**
     * 获取要绘制的颜色
     *
     * @param dwPenColor 输入颜色
     * @returns 输出颜色
     */
    override fun getPaintColor(dwPenColor: Long): Long {
        return getColor(dwPenColor)
    }

    /**
     * 获取偏移
     *
     * @return 偏移坐标
     */
    override fun getOffset(): FCPoint {
        return FCPoint(m_offsetX, m_offsetY)
    }

    override fun getScaleFactor(
        scaleFactorX: RefObject<Double>,
        scaleFactorY: RefObject<Double>
    ) {
        scaleFactorX.argvalue = m_scaleFactorX
        scaleFactorY.argvalue = m_scaleFactorY
    }

    /**
     * 旋转角度
     *
     * @param op    圆心坐标
     * @param mp    点的坐标
     * @param angle 角度
     * @return 结果坐标
     */
    override fun rotate(op: FCPoint, mp: FCPoint, angle: Int): FCPoint {
        val PI = 3.14159265f
        val pt = FCPoint()
        pt.x =
            ((mp.x - op.x) * Math.cos(angle * PI / 180.toDouble()) - (mp.y - op.y) * Math.sin(
                angle * PI / 180.toDouble()
            ) + op.x).toInt()
        pt.y =
            ((mp.x - op.x) * Math.sin(angle * PI / 180.toDouble()) + (mp.y - op.y) * Math.cos(
                angle * PI / 180.toDouble()
            ) + op.y).toInt()
        return pt
    }

    fun saveImage(key: String, value: Bitmap?) {
        m_images[key] = value
    }

    /**
     * 设置画布
     *
     * @param canvas 画布
     */
    fun setCanvas(canvas: Canvas?) {
        m_viewCanvas = canvas
    }

    /**
     * 设置裁剪区域
     *
     * @param rect 矩形区域
     */
    override fun setClip(rect: FCRect) {
        if (m_isClip) {
            m_canvas!!.restore()
        }
        var andriodRect = RectF(
            (rect.left + m_offsetX).toFloat(),
            (rect.top + m_offsetY).toFloat(),
            (rect.right + m_offsetX).toFloat(),
            (rect.bottom + m_offsetY).toFloat()
        )
        val refAndriodRect = RefObject(andriodRect)
        affectScaleFactor(refAndriodRect)
        andriodRect = refAndriodRect.argvalue
        m_canvas!!.save()
        m_isClip = true
        m_canvas!!.clipRect(andriodRect)
        m_paint!!.typeface = Typeface.DEFAULT
        m_lastFont = "Default"
    }

    /**
     * 设置画笔
     *
     * @param dwPenColor 颜色
     * @param width      宽度
     * @param style      样式
     */
    protected fun setDrawPaint(
        dwPenColor: Long,
        width: Float,
        style: Int
    ) {
        val aColor = getAndriodColor(dwPenColor).toLong()
        m_paint!!.color = getAndriodColor(dwPenColor)
        if (m_scaleFactorX != 1.0 || m_scaleFactorY != 1.0) {
            m_paint!!.strokeWidth = (width * Math.min(
                m_scaleFactorX,
                m_scaleFactorY
            )).toFloat()
        } else {
            m_paint!!.strokeWidth = width
        }
        m_paint!!.style = Paint.Style.STROKE
        if (style == 0) {
            m_paint!!.pathEffect = null
        } else if (style == 1) {
            m_paint!!.pathEffect = DashPathEffect(floatArrayOf(10f, 10f), 0.0f)
        } else if (style == 2) {
            m_paint!!.pathEffect = DashPathEffect(floatArrayOf(2f, 4f), 0.0f)
        }
    }

    /**
     * 设置填充画笔
     *
     * @param dwPenColor
     */
    protected fun setFillPaint(dwPenColor: Long) {
        m_paint!!.color = getAndriodColor(dwPenColor)
        m_paint!!.style = Paint.Style.FILL
    }

    /*
     * 设置直线两端的样式
     * @param lineCap 样式
     */
    override fun setLineCap(startLineCap: Int, endLineCap: Int) {
        if (endLineCap == 0) {
            m_paint!!.strokeCap = Paint.Cap.SQUARE
        } else if (endLineCap == 1) {
            m_paint!!.strokeCap = Paint.Cap.ROUND
        } else {
            m_paint!!.strokeCap = Paint.Cap.BUTT
        }
    }

    /**
     * 设置偏移
     *
     * @param mp 偏移坐标
     */
    override fun setOffset(mp: FCPoint) {
        m_offsetX = mp.x
        m_offsetY = mp.y
    }

    /**
     * 设置透明度
     *
     * @param opacity 透明度
     */
    override fun setOpacity(opacity: Float) {
        m_opacity = opacity
    }

    /**
     * 设置资源的路径
     *
     * @param resourcePath 资源的路径
     */
    override fun setResourcePath(resourcePath: String) {
        m_resourcePath = resourcePath
    }

    /**
     * 设置旋转角度
     *
     * @param rotateAngle 旋转角度
     */
    override fun setRotateAngle(rotateAngle: Int) {
        m_rotateAngle = rotateAngle
    }

    /**
     * 设置缩放因子
     *
     * @param scaleFactorX 横向因子
     * @param scaleFactorY 纵向因子
     */
    override fun setScaleFactor(
        scaleFactorX: Double,
        scaleFactorY: Double
    ) {
        m_scaleFactorX = scaleFactorX
        m_scaleFactorY = scaleFactorY
    }

    /**
     * 设置是否支持透明�?
     * * @return 是否支持
     */
    override fun supportTransparent(): Boolean {
        return true
    }

    /**
     * 获取文字大小
     *
     * @param text 文字
     * @param font 字体
     * @return 字体大小
     */
    override fun textSize(text: String, font: FCFont, width: Int): FCSize {
        return if (text != null) {
            val fontFamily = font.m_fontFamily
            var newFont = ""
            newFont = if (fontFamily == "Default") {
                MyColor.systemFont
            } else {
                font.m_fontFamily
            }
            if (newFont != m_lastFont) {
                if (newFont == "Default") {
                    m_paint!!.typeface = Typeface.DEFAULT
                } else {
                    try {
                        if (m_typeFaces.containsKey(newFont)) {
                            val tf = m_typeFaces[newFont]
                            if (tf !== m_paint!!.typeface) {
                                m_paint!!.typeface = m_typeFaces[newFont]
                            }
                        } else {
                            val tf =
                                Typeface.createFromFile("/system/fonts/$newFont.ttf")
                            if (tf != null) {
                                m_paint!!.typeface = tf
                                m_typeFaces[newFont] = tf
                            }
                        }
                    } catch (ex: Exception) {
                    }
                }
                m_lastFont = newFont
            }
            val rate = ((m_scaleFactorX + m_scaleFactorY) / 2).toFloat()
            m_paint!!.textSize = font.m_fontSize * rate
            m_paint!!.isFakeBoldText = font.m_bold
            m_paint!!.setTextSkewX(if (font.m_italic) -0.5f else 0.0f)
            m_paint!!.isUnderlineText = font.m_underline
            val fm = m_paint!!.fontMetrics
            FCSize((m_paint!!.measureText(text) / rate).toInt(), ((fm.descent - fm.ascent) / rate).toInt())
        } else {
            FCSize()
        }
    }

    /**
     * 获取文字大小
     *
     * @param text 文字
     * @param font 字体
     * @return 字体大小
     */
    override fun textSizeF(text: String, font: FCFont, width: Int): FCSizeF {
        return if (text != null) {
            val fontFamily = font.m_fontFamily
            var newFont = ""
            newFont = if (fontFamily == "Default") {
                MyColor.systemFont
            } else {
                font.m_fontFamily
            }
            if (newFont != m_lastFont) {
                if (newFont == "Default") {
                    m_paint!!.typeface = Typeface.DEFAULT
                } else {
                    try {
                        if (m_typeFaces.containsKey(newFont)) {
                            val tf = m_typeFaces[newFont]
                            if (tf !== m_paint!!.typeface) {
                                m_paint!!.typeface = m_typeFaces[newFont]
                            }
                        } else {
                            val tf =
                                Typeface.createFromFile("/system/fonts/$newFont.ttf")
                            if (tf != null) {
                                m_paint!!.typeface = tf
                                m_typeFaces[newFont] = tf
                            }
                        }
                    } catch (ex: Exception) {
                    }
                }
                m_lastFont = newFont
            }
            val rate = ((m_scaleFactorX + m_scaleFactorY) / 2).toFloat()
            m_paint!!.textSize = font.m_fontSize * rate
            m_paint!!.isFakeBoldText = font.m_bold
            m_paint!!.setTextSkewX(if (font.m_italic) -0.5f else 0.0f)
            m_paint!!.isUnderlineText = font.m_underline
            val fm = m_paint!!.fontMetrics
            FCSizeF(m_paint!!.measureText(text) / rate, (fm.descent - fm.ascent) / rate)
        } else {
            FCSizeF(0.0f, 0.0f)
        }
    }

    /*
    * 上次的字体
     */
    var m_lastFont = "Default"

    /*
    * 字体缓存
     */
    var m_typeFaces =
        HashMap<String, Typeface?>()

    companion object {
        /**
         * 角度
         */
        var m_angle = 0
    }
}